#include "authorizationtool.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
#include <stdexcept>
#include <vector>
#include <cmath>
#include "QDebug"
// Base36 字符集
const std::string BASE36_ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

// Base36 编码：将整数转换为指定长度的 Base36 字符串
std::string base36_encode(unsigned long long number, int length) {
    if (number < 0) {
        qWarning() << "Negative numbers cannot be encoded in Base36.";
        return std::string();
    }

    std::string base36 = "";
    do {
        unsigned long long remainder = number % 36;
        base36 = BASE36_ALPHABET[remainder] + base36;
        number /= 36;
    } while (number > 0);

    // 填充至指定长度
    if (base36.length() > static_cast<size_t>(length)) {
        // 如果编码后的字符串超过指定长度，抛出异常
        qWarning() << "Encoded Base36 string exceeds the specified length.";
        return std::string();
    }

    base36.insert(base36.begin(), length - base36.length(), '0');

    return base36;
}

// Base36 解码：将 Base36 字符串转换为整数
unsigned long long base36_decode(const std::string& str) {
    unsigned long long number = 0;
    for (char c : str) {
        number *= 36;
        if (c >= '0' && c <= '9') {
            number += (c - '0');
        }
        else if (c >= 'A' && c <= 'Z') {
            number += (c - 'A' + 10);
        }
        else {
            throw std::invalid_argument("Invalid character in Base36 string.");
        }
    }
    return number;
}

// 加密函数
std::string encrypt(const std::string& sequence_code, unsigned int timestamp) {
    if (sequence_code.length() < 6) {
        throw std::invalid_argument("sequence_code must have at least 6 characters.");
    }

    // 使用固定密钥进行异或加密（62位密钥）
    const unsigned long long KEY = 0x3FFFFFFFFFFFFFFF; // 62位密钥，可以根据需要更改

    // Step 1: 取前6位并转换为大写
    std::string seq_part = sequence_code.substr(0, 6);
    std::transform(seq_part.begin(), seq_part.end(), seq_part.begin(), ::toupper);

    // Step 2: 将序列码转换为整数（Base36）
    unsigned long long seq_int = base36_decode(seq_part);
    if (seq_int >= pow(36, 6)) {
        throw std::invalid_argument("sequence_code too large to encode in 6 Base36 characters.");
    }

    // Step 3: 确保时间戳在31位范围内
    if (timestamp >= (1u << 31)) {
        throw std::invalid_argument("timestamp must be a non-negative integer less than 2^31 (2147483648).");
    }

    // Step 4: 组合序列码和时间戳成62位整数
    unsigned long long combined = (seq_int << 31) | (timestamp & 0x7FFFFFFF); // 31位时间戳

    // Step 5: 使用密钥进行异或加密
    unsigned long long encrypted_int = combined ^ KEY;

    // Step 6: 将加密后的整数转换为12位Base36字符串
    std::string encrypted_str = base36_encode(encrypted_int, 12);

    return encrypted_str;
}

// 解密函数
std::pair<std::string, unsigned int> decrypt(const std::string& encrypted_str) {
    if (encrypted_str.length() != 12) {
        qWarning() << "encrypted_str must be exactly 12 characters long.";
        return {std::string(), int()};
    }

    // 将字符串转换为大写
    std::string upper_encrypted_str = encrypted_str;
    std::transform(upper_encrypted_str.begin(), upper_encrypted_str.end(), upper_encrypted_str.begin(), ::toupper);

    // 使用固定密钥进行异或解密（62位密钥）
    const unsigned long long KEY = 0x3FFFFFFFFFFFFFFF; // 62位密钥，必须与加密时相同

    // Step 1: 将加密字符串转换为整数
    unsigned long long encrypted_int = base36_decode(upper_encrypted_str);

    if (encrypted_int >= pow(36, 12)) {
        qWarning() << "encrypted_str is too large to decode from 12 Base36 characters.";
        return {std::string(), int()};
    }

    // Step 2: 使用密钥进行异或解密
    unsigned long long combined = encrypted_int ^ KEY;

    // Step 3: 提取序列码和时间戳
    unsigned long long seq_int = combined >> 31;
    unsigned int timestamp = combined & 0x7FFFFFFF; // 获取低31位作为时间戳

    // Step 4: 将序列码整数转换回Base36字符串
    std::string sequence_code = base36_encode(seq_int, 6);

    return {sequence_code, timestamp};
}
